Next: Iteration, Previous: Conditionals, Up: Control Structure [Contents][Index]
Common Lisp blocks provide a non-local exit mechanism
very similar to catch and throw, with
lexical scoping. This package actually implements
cl-block in terms of catch; however,
the lexical scoping allows the byte-compiler to omit the costly
catch step if the body of the block does not
actually cl-return-from the block.
The forms are evaluated as if by a
progn. However, if any of the forms
execute (cl-return-from name), they
will jump out and return directly from the
cl-block form. The cl-block returns
the result of the last form unless a
cl-return-from occurs.
The cl-block/cl-return-from
mechanism is quite similar to the
catch/throw mechanism. The main
differences are that block names are unevaluated
symbols, rather than forms (such as quoted symbols) that
evaluate to a tag at run-time; and also that blocks are
always lexically scoped. In a dynamically scoped
catch, functions called from the
catch body can also throw to the
catch. This is not an option for
cl-block, where the cl-return-from
referring to a block name must appear physically within the
forms that make up the body of the block. They may
not appear within other called functions, although they may
appear within macro expansions or lambdas in the
body. Block names and catch names form
independent name-spaces.
In true Common Lisp, defun and
defmacro surround the function or expander
bodies with implicit blocks with the same name as the
function or macro. This does not occur in Emacs Lisp, but
this package provides cl-defun and
cl-defmacro forms, which do create the implicit
block.
The Common Lisp looping constructs defined by this
package, such as cl-loop and
cl-dolist, also create implicit blocks just as
in Common Lisp.
Because they are implemented in terms of Emacs
Lisp’s catch and throw,
blocks have the same overhead as actual catch
constructs (roughly two function calls). However, the byte
compiler will optimize away the catch if the
block does not in fact contain any cl-return or
cl-return-from calls that jump to it. This means
that cl-do loops and cl-defun
functions that don’t use cl-return
don’t pay the overhead to support it.
This macro returns from the block named name,
which must be an (unevaluated) symbol. If a result
form is specified, it is evaluated to produce the result
returned from the block. Otherwise,
nil is returned.
This macro is exactly like (cl-return-from nil
result). Common Lisp loops like
cl-do and cl-dolist implicitly
enclose themselves in nil blocks.
This macro executes statements while allowing for control
transfer to user-defined labels. Each element of
labels-or-statements can be either a label (an
integer or a symbol), or a cons-cell (a statement). This
distinction is made before macroexpansion. Statements are
executed in sequence, discarding any return value. Any
statement can transfer control at any time to the statements
that follow one of the labels with the special form (go
label). Labels have lexical scope and
dynamic extent.
Next: Iteration, Previous: Conditionals, Up: Control Structure [Contents][Index]